library(tidyverse)
library(dplyr, warn.conflicts = FALSE)
library(here)
library(plotly)
library(scales)
library(highcharter)
library(stringr)
theme_set(theme_bw())

Data Overview

data <- read_csv(here::here("data/jackson.csv"), 
                            col_types = cols(
                                .default = col_double(),
                                album_uri = col_character(),
                                album_name = col_character(),
                                album_img = col_character(),
                                album_release_date = col_character(),
                                album_release_year = col_date(format = ""),
                                album_popularity = col_integer(),
                                track_name = col_character(),
                                track_uri = col_character(),
                                key = col_character(),
                                mode = col_character(),
                                time_signature = col_integer(),
                                key_mode = col_character(),
                                track_popularity = col_integer()
                                )) %>%
         mutate(album_name = gsub(".*(1954).*",
                                         "The Music of Brazil/Jackson do Pandeiro",
                                  album_name));
data %>% 
    glimpse()
Observations: 500
Variables: 23
$ album_uri          <chr> "5T9tTjPIfjbUJGRJdYOOLl", "5T9tTjPIfjbUJGRJdYOOLl", "5T9tTjPIfjb...
$ album_name         <chr> "Jackson Do Pandeiro Volume 1: Tum, Tum, Tum!", "Jackson Do Pand...
$ album_img          <chr> "https://i.scdn.co/image/5dcc4a0cad740f1ee0774196d0a14f3693ef887...
$ album_release_date <chr> "1958-11-11", "1958-11-11", "1958-11-11", "1958-11-11", "1958-11...
$ album_release_year <date> 1958-11-11, 1958-11-11, 1958-11-11, 1958-11-11, 1958-11-11, 195...
$ album_popularity   <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...
$ track_name         <chr> "Tum, Tum, Tum", "Pacífico Pacato", "Nortista Quatrocentão", "Se...
$ track_uri          <chr> "6cCYhV6fU68uzbjWPG9V7x", "6Gu7y9SgtVTGh8YGhDPtCe", "1hq7M7cJtvD...
$ danceability       <dbl> 0.501, 0.663, 0.550, 0.447, 0.544, 0.571, 0.495, 0.572, 0.500, 0...
$ energy             <dbl> 0.987, 0.962, 0.947, 0.969, 0.972, 0.926, 0.967, 0.986, 0.947, 0...
$ key                <chr> "A", "F", "D", "G", "E", "F", "E", "C", "F", "A#", "E", "F", "D#...
$ loudness           <dbl> 2.561, 1.137, 1.621, 2.743, 2.513, 2.414, 2.375, 2.597, 3.078, 3...
$ mode               <chr> "major", "major", "major", "major", "minor", "major", "minor", "...
$ speechiness        <dbl> 0.0429, 0.1810, 0.0469, 0.0549, 0.0502, 0.0344, 0.0576, 0.0367, ...
$ acousticness       <dbl> 0.718, 0.738, 0.666, 0.759, 0.787, 0.651, 0.712, 0.194, 0.286, 0...
$ instrumentalness   <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...
$ liveness           <dbl> 0.282, 0.200, 0.251, 0.333, 0.176, 0.342, 0.321, 0.301, 0.323, 0...
$ valence            <dbl> 0.963, 0.961, 0.923, 0.899, 0.783, 0.961, 0.755, 0.989, 0.957, 0...
$ tempo              <dbl> 101.676, 113.562, 116.125, 116.023, 112.863, 133.065, 117.822, 1...
$ duration_ms        <dbl> 158133, 139773, 163173, 143733, 151653, 157480, 158133, 154680, ...
$ time_signature     <int> 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4...
$ key_mode           <chr> "A major", "F major", "D major", "G major", "E minor", "F major"...
$ track_popularity   <int> 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0...

Danceability

data %>% 
    ggplot(aes(sample=danceability)) + 
        stat_qq()

hchart (data$danceability,
        color = "#B71C1C",
        name = "Dançabilidade")

Speechines

data %>% 
    ggplot(aes(sample=speechiness)) + 
        stat_qq()

hchart (data$speechiness,
        color = "#B71C1C",
        name = "Verbosidade")

Duration

data <- data %>%
    mutate(duration_s = duration_ms/1000)
data %>% 
    select(duration_s) %>%
    glimpse()
Observations: 500
Variables: 1
$ duration_s <dbl> 158.133, 139.773, 163.173, 143.733, 151.653, 157.480, 158.133, 154.680, ...
data %>% 
    ggplot(aes(sample=duration_s)) + 
        stat_qq()

hchart (data$duration_s,
        color = "#B71C1C",
        name = "Duração (s)")

Remaster

Ultimo album “1981: Isso é que é Forró!”

data <- data %>%
    mutate(remaster = album_release_date > "1981-30-12")
data %>% 
    select(album_name, album_release_year, remaster) %>%
    sample_n(10)
temp <- data %>% 
    distinct(album_name,
             .keep_all = TRUE) %>%
    mutate(remaster = ifelse(remaster == TRUE,"remasterizado","original"))
hchart(temp$remaster,
       colorByPoint = TRUE,
       name="Álbum")

Mais discurso/diálogo (speechines) tem efeito sobre a dançabilidade da música?

p <- data %>% 
        distinct(track_name, .keep_all = TRUE) %>%
        ggplot(aes(x=speechiness,
                   y=danceability)) +
        geom_point(alpha=0.4) 
ggplotly(p)

A dançabilidade das músicas de Jackson

data %>% 
    distinct(track_name, .keep_all = TRUE) %>%
    ggplot(aes(speechiness,danceability)) +
    stat_density2d(aes(fill = ..level..), geom = "polygon")

data %>%
    group_by(track_name) %>%
    top_n(10, speechiness)

Como o passar dos anos afeta o tempo de duração da música?

temp <-
    data %>% 
    distinct(album_name, .keep_all = TRUE) %>%
    group_by(album_release_year) %>%
    summarise(original_n = sum(!remaster),
              remaster_n = sum(remaster))
highchart() %>%
  hc_xAxis(categories = temp$album_release_year) %>%
  hc_add_series(temp$original_n, 
                type = "column",
                color = "#B71C1C",
                name = "Não remasterizado") %>%
  hc_add_series(temp$remaster_n, 
                type = "column",
                name = "Remasterizado")  %>%
      hc_title(text = "Número de álbuns por ano")
m <- list(
  l =70,
  b = 150)
p <- data %>% 
    ggplot(aes(x=as.factor(album_release_year),
               duration_s,
               group=album_release_year,
               color=remaster)) +
    geom_boxplot(position = "dodge", alpha=0.6) +
    theme(axis.text.x = element_text(angle = 30, hjust = 1))
ggplotly(p) %>%
     layout(autosize = F, margin=m)

Os albuns relançados/remasterizados são mais populares?

# lollipop chart
m <- list(
  l = 370)
p <- data %>%
        ggplot(aes(album_popularity,y=reorder(album_name,album_popularity),
                   color=remaster,
                   group=remaster)) +
            geom_segment(aes(x = 0, y = reorder(album_name,album_popularity), 
                             xend = album_popularity, 
                             yend = album_name)) + 
        geom_point() +
        theme(axis.title.y=element_blank())
ggplotly(p,tooltip=NA) %>%
  layout(autosize = F,
         margin = m)

De Qual nota são as faixas mais populares?

# tim12equal = c("#00008F", "#0000EA", "#0047FF", "#00A2FF", "#00FEFF", "#5AFFA5", "#B5FF4A", "#FFED00", "#FF9200", "#FF3700", "#DB0000", "#800000")
# 
# m <- list(
#     b = 70);
# 
# p <- 
#  data %>%
#     select(key,album_release_date) %>%
#     group_by(album_release_date,key) %>%
#     summarise(count = n()) %>%
#     mutate(prop = count/sum(count)) %>%
#     ungroup() %>%
#     ggplot(aes(x = factor(album_release_date), y = count, fill = key)) +
#     geom_bar(stat = "identity", position = "fill", width = .7)  +
#     scale_y_continuous(labels = scales::percent) +
#     scale_fill_manual(values = tim12equal) +
#     theme(axis.text.x = element_text(angle = 30, hjust = 1)) + 
#     ggtitle("Distribuição de notas musicais temporalmente")
# 
# 
# ggplotly(p) %>%
#       layout(autosize = F,
#              margin = m)
tim12equal = c("#00008F", "#0000EA", "#0047FF", "#00A2FF", "#00FEFF", "#5AFFA5", "#B5FF4A", "#FFED00", "#FF9200", "#FF3700", "#DB0000", "#800000")
m <- list(
    l=80,
    r=30);
p <-  data %>%
    select(key,album_release_date, remaster) %>%
    group_by(album_release_date,key,remaster) %>%
    summarise(count = n()) %>%
    mutate(prop = count/sum(count)) %>%
    ungroup() %>%
    ggplot(aes(x = factor(album_release_date), y = count, fill = key)) +
    geom_bar(stat = "identity", position = "fill", width = .7)  +
    scale_y_continuous(labels = scales::percent) +
    scale_fill_manual(values = tim12equal) +
    theme(axis.text.x = element_text(angle = 30, hjust = 1))  +
    theme(axis.title.x=element_blank(),
          axis.title.y=element_blank()) +
    facet_grid(remaster ~ .) +
    ggtitle("Notas musicais (distinção por remasterização)") +
    guides(fill=guide_legend(title=""))
ggplotly(p) %>%
      layout(autosize = F,
             margin = m,
             legend = list(
      orientation = "h", y =-0.2
    ))

É possível ver que no começo dos anos 1960 ínicio as músicas na escala entre E e G dominam fortemente o repertório de Jackson, curiosamente quando as músicas de notas entre A e C chegam a ocupar metade das ocorrências. Isso está de acordo com o perfil de Jackson, notório por sua heterogeneidade.

LS0tCnRpdGxlOiAiRURBIFZJUyBjYW7Dp8O1ZXMiCnN1YnRpdGxlOiAnQW7DoWxpc2Ugc29icmUgSmFja3NvbiBkbyBQYW5kZWlybycKYXV0aG9yOiAiSm9zw6kgQmVuYXJkaSBkZSBTb3V6YSBOdW5lcyIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKLS0tCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZHBseXIsIHdhcm4uY29uZmxpY3RzID0gRkFMU0UpCmxpYnJhcnkoaGVyZSkKbGlicmFyeShwbG90bHkpCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KGhpZ2hjaGFydGVyKQpsaWJyYXJ5KHN0cmluZ3IpCnRoZW1lX3NldCh0aGVtZV9idygpKQpgYGAKCiMjIERhdGEgT3ZlcnZpZXcKCmBgYHtyfQpkYXRhIDwtIHJlYWRfY3N2KGhlcmU6OmhlcmUoImRhdGEvamFja3Nvbi5jc3YiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSBjb2xzKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5kZWZhdWx0ID0gY29sX2RvdWJsZSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsYnVtX3VyaSA9IGNvbF9jaGFyYWN0ZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGJ1bV9uYW1lID0gY29sX2NoYXJhY3RlcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsYnVtX2ltZyA9IGNvbF9jaGFyYWN0ZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGJ1bV9yZWxlYXNlX2RhdGUgPSBjb2xfY2hhcmFjdGVyKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxidW1fcmVsZWFzZV95ZWFyID0gY29sX2RhdGUoZm9ybWF0ID0gIiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsYnVtX3BvcHVsYXJpdHkgPSBjb2xfaW50ZWdlcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYWNrX25hbWUgPSBjb2xfY2hhcmFjdGVyKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhY2tfdXJpID0gY29sX2NoYXJhY3RlcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGNvbF9jaGFyYWN0ZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlID0gY29sX2NoYXJhY3RlcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVfc2lnbmF0dXJlID0gY29sX2ludGVnZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlfbW9kZSA9IGNvbF9jaGFyYWN0ZXIoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFja19wb3B1bGFyaXR5ID0gY29sX2ludGVnZXIoKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkpICU+JQogICAgICAgICBtdXRhdGUoYWxidW1fbmFtZSA9IGdzdWIoIi4qKDE5NTQpLioiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUaGUgTXVzaWMgb2YgQnJhemlsL0phY2tzb24gZG8gUGFuZGVpcm8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxidW1fbmFtZSkpOwpkYXRhICU+JSAKICAgIGdsaW1wc2UoKQpgYGAKCiMjIyBEYW5jZWFiaWxpdHkKCmBgYHtyfQpkYXRhICU+JSAKICAgIGdncGxvdChhZXMoc2FtcGxlPWRhbmNlYWJpbGl0eSkpICsgCiAgICAgICAgc3RhdF9xcSgpCmBgYAoKYGBge3J9CmhjaGFydCAoZGF0YSRkYW5jZWFiaWxpdHksCiAgICAgICAgY29sb3IgPSAiI0I3MUMxQyIsCiAgICAgICAgbmFtZSA9ICJEYW7Dp2FiaWxpZGFkZSIpCmBgYAoKCiMjIyBTcGVlY2hpbmVzCgpgYGB7cn0KZGF0YSAlPiUgCiAgICBnZ3Bsb3QoYWVzKHNhbXBsZT1zcGVlY2hpbmVzcykpICsgCiAgICAgICAgc3RhdF9xcSgpCmBgYAoKYGBge3J9CmhjaGFydCAoZGF0YSRzcGVlY2hpbmVzcywKICAgICAgICBjb2xvciA9ICIjQjcxQzFDIiwKICAgICAgICBuYW1lID0gIlZlcmJvc2lkYWRlIikKYGBgCgojIyMgRHVyYXRpb24KCmBgYHtyfQpkYXRhIDwtIGRhdGEgJT4lCiAgICBtdXRhdGUoZHVyYXRpb25fcyA9IGR1cmF0aW9uX21zLzEwMDApCgpkYXRhICU+JSAKICAgIHNlbGVjdChkdXJhdGlvbl9zKSAlPiUKICAgIGdsaW1wc2UoKQpgYGAKCgpgYGB7cn0KZGF0YSAlPiUgCiAgICBnZ3Bsb3QoYWVzKHNhbXBsZT1kdXJhdGlvbl9zKSkgKyAKICAgICAgICBzdGF0X3FxKCkKYGBgCgpgYGB7cn0KaGNoYXJ0IChkYXRhJGR1cmF0aW9uX3MsCiAgICAgICAgY29sb3IgPSAiI0I3MUMxQyIsCiAgICAgICAgbmFtZSA9ICJEdXJhw6fDo28gKHMpIikKYGBgCgojIyMgUmVtYXN0ZXIKClVsdGltbyBhbGJ1bSAiMTk4MTogSXNzbyDDqSBxdWUgw6kgRm9ycsOzISIKCmBgYHtyfQpkYXRhIDwtIGRhdGEgJT4lCiAgICBtdXRhdGUocmVtYXN0ZXIgPSBhbGJ1bV9yZWxlYXNlX2RhdGUgPiAiMTk4MS0zMC0xMiIpCgpkYXRhICU+JSAKICAgIHNlbGVjdChhbGJ1bV9uYW1lLCBhbGJ1bV9yZWxlYXNlX3llYXIsIHJlbWFzdGVyKSAlPiUKICAgIHNhbXBsZV9uKDEwKQpgYGAKCgpgYGB7cn0KdGVtcCA8LSBkYXRhICU+JSAKICAgIGRpc3RpbmN0KGFsYnVtX25hbWUsCiAgICAgICAgICAgICAua2VlcF9hbGwgPSBUUlVFKSAlPiUKICAgIG11dGF0ZShyZW1hc3RlciA9IGlmZWxzZShyZW1hc3RlciA9PSBUUlVFLCJyZW1hc3Rlcml6YWRvIiwib3JpZ2luYWwiKSkKCmhjaGFydCh0ZW1wJHJlbWFzdGVyLAogICAgICAgY29sb3JCeVBvaW50ID0gVFJVRSwKICAgICAgIG5hbWU9IsOBbGJ1bSIpCmBgYAoKCgojIyBNYWlzIGRpc2N1cnNvL2Rpw6Fsb2dvIChzcGVlY2hpbmVzKSB0ZW0gZWZlaXRvIHNvYnJlIGEgZGFuw6dhYmlsaWRhZGUgZGEgbcO6c2ljYT8KCmBgYHtyfQpwIDwtIGRhdGEgJT4lIAogICAgICAgIGRpc3RpbmN0KHRyYWNrX25hbWUsIC5rZWVwX2FsbCA9IFRSVUUpICU+JQogICAgICAgIGdncGxvdChhZXMoeD1zcGVlY2hpbmVzcywKICAgICAgICAgICAgICAgICAgIHk9ZGFuY2VhYmlsaXR5KSkgKwogICAgICAgIGdlb21fcG9pbnQoYWxwaGE9MC40KSAKCmdncGxvdGx5KHApCmBgYAoKQSBkYW7Dp2FiaWxpZGFkZSBkYXMgbcO6c2ljYXMgZGUgSmFja3NvbgoKYGBge3J9CmRhdGEgJT4lIAogICAgZGlzdGluY3QodHJhY2tfbmFtZSwgLmtlZXBfYWxsID0gVFJVRSkgJT4lCiAgICBnZ3Bsb3QoYWVzKHNwZWVjaGluZXNzLGRhbmNlYWJpbGl0eSkpICsKICAgIHN0YXRfZGVuc2l0eTJkKGFlcyhmaWxsID0gLi5sZXZlbC4uKSwgZ2VvbSA9ICJwb2x5Z29uIikKYGBgCgpgYGB7cn0KZGF0YSAlPiUKICAgIGdyb3VwX2J5KHRyYWNrX25hbWUpICU+JQogICAgdG9wX24oMTAsIHNwZWVjaGluZXNzKQpgYGAKCiMjIENvbW8gbyBwYXNzYXIgZG9zIGFub3MgYWZldGEgbyB0ZW1wbyBkZSBkdXJhw6fDo28gZGEgbcO6c2ljYT8KCmBgYHtyfQp0ZW1wIDwtCiAgICBkYXRhICU+JSAKICAgIGRpc3RpbmN0KGFsYnVtX25hbWUsIC5rZWVwX2FsbCA9IFRSVUUpICU+JQogICAgZ3JvdXBfYnkoYWxidW1fcmVsZWFzZV95ZWFyKSAlPiUKICAgIHN1bW1hcmlzZShvcmlnaW5hbF9uID0gc3VtKCFyZW1hc3RlciksCiAgICAgICAgICAgICAgcmVtYXN0ZXJfbiA9IHN1bShyZW1hc3RlcikpCgpoaWdoY2hhcnQoKSAlPiUKCiAgaGNfeEF4aXMoY2F0ZWdvcmllcyA9IHRlbXAkYWxidW1fcmVsZWFzZV95ZWFyKSAlPiUKICBoY19hZGRfc2VyaWVzKHRlbXAkb3JpZ2luYWxfbiwgCiAgICAgICAgICAgICAgICB0eXBlID0gImNvbHVtbiIsCiAgICAgICAgICAgICAgICBjb2xvciA9ICIjQjcxQzFDIiwKICAgICAgICAgICAgICAgIG5hbWUgPSAiTsOjbyByZW1hc3Rlcml6YWRvIikgJT4lCiAgaGNfYWRkX3Nlcmllcyh0ZW1wJHJlbWFzdGVyX24sIAogICAgICAgICAgICAgICAgdHlwZSA9ICJjb2x1bW4iLAogICAgICAgICAgICAgICAgbmFtZSA9ICJSZW1hc3Rlcml6YWRvIikgICU+JQogICAgICBoY190aXRsZSh0ZXh0ID0gIk7Dum1lcm8gZGUgw6FsYnVucyBwb3IgYW5vIikKCmBgYAoKYGBge3J9Cm0gPC0gbGlzdCgKICBsID03MCwKICBiID0gMTUwKQoKcCA8LSBkYXRhICU+JSAKICAgIGdncGxvdChhZXMoeD1hcy5mYWN0b3IoYWxidW1fcmVsZWFzZV95ZWFyKSwKICAgICAgICAgICAgICAgZHVyYXRpb25fcywKICAgICAgICAgICAgICAgZ3JvdXA9YWxidW1fcmVsZWFzZV95ZWFyLAogICAgICAgICAgICAgICBjb2xvcj1yZW1hc3RlcikpICsKICAgIGdlb21fYm94cGxvdChwb3NpdGlvbiA9ICJkb2RnZSIsIGFscGhhPTAuNikgKwogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPSAxKSkKCmdncGxvdGx5KHApICU+JQogICAgIGxheW91dChhdXRvc2l6ZSA9IEYsIG1hcmdpbj1tKQpgYGAKCiMjIE9zIGFsYnVucyByZWxhbsOnYWRvcy9yZW1hc3Rlcml6YWRvcyBzw6NvIG1haXMgcG9wdWxhcmVzPyAKCmBgYHtyfQojIGxvbGxpcG9wIGNoYXJ0Cm0gPC0gbGlzdCgKICBsID0gMzcwKQoKcCA8LSBkYXRhICU+JQogICAgICAgIGdncGxvdChhZXMoYWxidW1fcG9wdWxhcml0eSx5PXJlb3JkZXIoYWxidW1fbmFtZSxhbGJ1bV9wb3B1bGFyaXR5KSwKICAgICAgICAgICAgICAgICAgIGNvbG9yPXJlbWFzdGVyLAogICAgICAgICAgICAgICAgICAgZ3JvdXA9cmVtYXN0ZXIpKSArCiAgICAgICAgICAgIGdlb21fc2VnbWVudChhZXMoeCA9IDAsIHkgPSByZW9yZGVyKGFsYnVtX25hbWUsYWxidW1fcG9wdWxhcml0eSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhlbmQgPSBhbGJ1bV9wb3B1bGFyaXR5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZW5kID0gYWxidW1fbmFtZSkpICsgCiAgICAgICAgZ2VvbV9wb2ludCgpICsKICAgICAgICB0aGVtZShheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpKQoKZ2dwbG90bHkocCx0b29sdGlwPU5BKSAlPiUKICBsYXlvdXQoYXV0b3NpemUgPSBGLAogICAgICAgICBtYXJnaW4gPSBtKQpgYGAKCiMjIERlIFF1YWwgbm90YSBzw6NvIGFzIGZhaXhhcyBtYWlzIHBvcHVsYXJlcz8KCgpgYGB7cn0KIyB0aW0xMmVxdWFsID0gYygiIzAwMDA4RiIsICIjMDAwMEVBIiwgIiMwMDQ3RkYiLCAiIzAwQTJGRiIsICIjMDBGRUZGIiwgIiM1QUZGQTUiLCAiI0I1RkY0QSIsICIjRkZFRDAwIiwgIiNGRjkyMDAiLCAiI0ZGMzcwMCIsICIjREIwMDAwIiwgIiM4MDAwMDAiKQojIAojIG0gPC0gbGlzdCgKIyAgICAgYiA9IDcwKTsKIyAKIyBwIDwtIAojICBkYXRhICU+JQojICAgICBzZWxlY3Qoa2V5LGFsYnVtX3JlbGVhc2VfZGF0ZSkgJT4lCiMgICAgIGdyb3VwX2J5KGFsYnVtX3JlbGVhc2VfZGF0ZSxrZXkpICU+JQojICAgICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JQojICAgICBtdXRhdGUocHJvcCA9IGNvdW50L3N1bShjb3VudCkpICU+JQojICAgICB1bmdyb3VwKCkgJT4lCiMgICAgIGdncGxvdChhZXMoeCA9IGZhY3RvcihhbGJ1bV9yZWxlYXNlX2RhdGUpLCB5ID0gY291bnQsIGZpbGwgPSBrZXkpKSArCiMgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJmaWxsIiwgd2lkdGggPSAuNykgICsKIyAgICAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkgKwojICAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSB0aW0xMmVxdWFsKSArCiMgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSkpICsgCiMgICAgIGdndGl0bGUoIkRpc3RyaWJ1acOnw6NvIGRlIG5vdGFzIG11c2ljYWlzIHRlbXBvcmFsbWVudGUiKQojIAojIAojIGdncGxvdGx5KHApICU+JQojICAgICAgIGxheW91dChhdXRvc2l6ZSA9IEYsCiMgICAgICAgICAgICAgIG1hcmdpbiA9IG0pCmBgYAoKCgoKYGBge3J9CnRpbTEyZXF1YWwgPSBjKCIjMDAwMDhGIiwgIiMwMDAwRUEiLCAiIzAwNDdGRiIsICIjMDBBMkZGIiwgIiMwMEZFRkYiLCAiIzVBRkZBNSIsICIjQjVGRjRBIiwgIiNGRkVEMDAiLCAiI0ZGOTIwMCIsICIjRkYzNzAwIiwgIiNEQjAwMDAiLCAiIzgwMDAwMCIpCgoKbSA8LSBsaXN0KAogICAgbD04MCwKICAgIHI9MzApOwoKcCA8LSAgZGF0YSAlPiUKICAgIHNlbGVjdChrZXksYWxidW1fcmVsZWFzZV9kYXRlLCByZW1hc3RlcikgJT4lCiAgICBncm91cF9ieShhbGJ1bV9yZWxlYXNlX2RhdGUsa2V5LHJlbWFzdGVyKSAlPiUKICAgIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lCiAgICBtdXRhdGUocHJvcCA9IGNvdW50L3N1bShjb3VudCkpICU+JQogICAgdW5ncm91cCgpICU+JQogICAgZ2dwbG90KGFlcyh4ID0gZmFjdG9yKGFsYnVtX3JlbGVhc2VfZGF0ZSksIHkgPSBjb3VudCwgZmlsbCA9IGtleSkpICsKICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJmaWxsIiwgd2lkdGggPSAuNykgICsKICAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsKICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHRpbTEyZXF1YWwpICsKICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0gMSkpICArCiAgICB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSkgKwogICAgZmFjZXRfZ3JpZChyZW1hc3RlciB+IC4pICsKICAgIGdndGl0bGUoIk5vdGFzIG11c2ljYWlzIChkaXN0aW7Dp8OjbyBwb3IgcmVtYXN0ZXJpemHDp8OjbykiKSArCiAgICBndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9IiIpKQoKZ2dwbG90bHkocCkgJT4lCiAgICAgIGxheW91dChhdXRvc2l6ZSA9IEYsCiAgICAgICAgICAgICBtYXJnaW4gPSBtLAogICAgICAgICAgICAgbGVnZW5kID0gbGlzdCgKICAgICAgb3JpZW50YXRpb24gPSAiaCIsIHkgPS0wLjIKICAgICkpCgpgYGAKCsOJIHBvc3PDrXZlbCB2ZXIgcXVlIG5vIGNvbWXDp28gZG9zIGFub3MgMTk2MCDDrW5pY2lvIGFzIG3DunNpY2FzIG5hIGVzY2FsYSBlbnRyZSBFIGUgRyBkb21pbmFtIGZvcnRlbWVudGUgbyByZXBlcnTDs3JpbyBkZSBKYWNrc29uLCBjdXJpb3NhbWVudGUgcXVhbmRvIGFzIG3DunNpY2FzIGRlIG5vdGFzIGVudHJlIEEgZSBDIGNoZWdhbSBhIG9jdXBhciBtZXRhZGUgZGFzIG9jb3Jyw6puY2lhcy4gSXNzbyBlc3TDoSBkZSBhY29yZG8gY29tIG8gcGVyZmlsIGRlIEphY2tzb24sIG5vdMOzcmlvIHBvciBzdWEgaGV0ZXJvZ2VuZWlkYWRlLgoKCgo=